<?php
/**
 * crcl/base
 *
 * Copyright 2013 CRCL - André Sabosch - info@crcl.de
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * Handling base pathes
 */

namespace crcl\base\base;

interface IPath
{
  /**
   * Replaces PATH constants
   * DIR_BASE_x
   *
   * @param string $sPath  Directory to be replaced
   * @return string
   */
  public static function replaceConstants($sPath);
}

class Path implements IPath
{
  public static function replaceConstants($sPath)
  {
    $sPath = self::replaceDirectory($sPath, self::DIR_CONFIGS);
    $sPath = self::replaceDirectory($sPath, self::DIR_TESTS);
    return $sPath;
  }

  /** PRIVATE *************************************************************************************/

  const DIR_CONFIGS = 'DIR_BASE_CONFIGS';
  const DIR_TESTS   = 'DIR_BASE_TESTS';

  private static $aCacheDirectories = array();

  private static function replaceDirectory($sPath, $sSearch)
  {
    $sDirectory = self::getDirectory($sSearch);
    $sSearch = '%' . $sSearch . '%';
    $iPos = \strpos($sPath, $sSearch);
    if ($iPos !== \FALSE)
    {
      if ($iPos > 0)
      {
        if ($sPath[$iPos-1] == '/')
        {
          $sDirectory = \crcl\base\String::getInstance($sDirectory)
            ->doNotStartWith('/')
            ->toString();
          //drive letter, windows?
          if (\strlen($sDirectory) > 2)
          {
            if ($sDirectory[1] == ':') //Drive letter
            {
              $sPath = \substr($sPath, 0, $iPos-1) . \substr($sPath, $iPos);
              //calculate new iPos for next test
              $iPos = \strpos($sPath, $sSearch);
            }
          }
        }
      }
      if (\strlen($sPath) > $iPos + \strlen($sSearch))
      {
        if ($sPath[$iPos+\strlen($sSearch)] == '/')
        {
          $sDirectory = \crcl\base\String::getInstance($sDirectory)->doNotEndWith('/');
        }
      }
      $sPath = \str_replace($sSearch, $sDirectory, $sPath);
    }
    return $sPath;
  }

  private static function getDirectory($sType)
  {
    if (isset(self::$aCacheDirectories[$sType]))
    {
      return self::$aCacheDirectories[$sType];
    }
    $sFile = new \crcl\base\File(__FILE__); //normalize
    $sRoot = dirname(\dirname($sFile));
    $sRoot .= '/'; //dont use DIRECTORY_SEPARATION: we use normalized pathes
    switch ($sType)
    {
//      case self::DIR_ETC:
//        $sDir = \dirname(\dirname($sRoot));
//        break;
//      case self::DIR_ROOT:
//        $sDir = $sRoot;
//        break;
//      case self::DIR_CERTIFICATES:
//        $sDir = $sRoot . 'common/certificates';
//        break;
      case self::DIR_CONFIGS:
        $sDir = $sRoot . 'common/configs/';
        break;
//      case self::DIR_TABLES:
//        $sDir = $sRoot . 'common/tables';
//        break;
//      case self::DIR_FORMS:
//        $sDir = $sRoot . 'common/forms';
//        break;
//      case self::DIR_I18N:
//        $sDir = $sRoot . 'common/i18n';
//        break;
      case self::DIR_TESTS:
        $sDir = \dirname(dirname(\dirname($sRoot)));
        $sDir .= '/tests/';
        break;

    }
    self::$aCacheDirectories[$sType] = $sDir;
    return $sDir;
  }
}